package com.github.jlmd.animatedcircleloadingview;

import com.github.jlmd.animatedcircleloadingview.animator.ViewAnimator;
import com.github.jlmd.animatedcircleloadingview.component.InitialCenterCircleView;
import com.github.jlmd.animatedcircleloadingview.component.MainCircleView;
import com.github.jlmd.animatedcircleloadingview.component.PercentIndicatorView;
import com.github.jlmd.animatedcircleloadingview.component.RightCircleView;
import com.github.jlmd.animatedcircleloadingview.component.SideArcsView;
import com.github.jlmd.animatedcircleloadingview.component.TopCircleBorderView;
import com.github.jlmd.animatedcircleloadingview.component.finish.FinishedFailureView;
import com.github.jlmd.animatedcircleloadingview.component.finish.FinishedOkView;
import com.github.jlmd.animatedcircleloadingview.util.AttrUtil;

import ohos.agp.components.AttrSet;
import ohos.agp.components.StackLayout;
import ohos.agp.utils.Color;
import ohos.app.Context;

/**
 * @author jlmd
 */
public class AnimatedCircleLoadingView extends StackLayout {
    private static final int DEFAULT_HEX_MAIN_COLOR = 0xFF9A00;
    private static final int DEFAULT_HEX_SECONDARY_COLOR = 0xBDBDBD;
    private static final int DEFAULT_HEX_TINT_COLOR = 0xFFFFFF;
    private static final int DEFAULT_HEX_TEXT_COLOR = 0xFFFFFF;
    private final Context context;
    private InitialCenterCircleView initialCenterCircleView;
    private MainCircleView mainCircleView;
    private RightCircleView rightCircleView;
    private SideArcsView sideArcsView;
    private TopCircleBorderView topCircleBorderView;
    private FinishedOkView finishedOkView;
    private FinishedFailureView finishedFailureView;
    private PercentIndicatorView percentIndicatorView;
    private ViewAnimator viewAnimator;
    private AnimationListener animationListener;
    private boolean startAnimationIndeterminate;
    private boolean startAnimationDeterminate;
    private boolean stopAnimationOk;
    private boolean stopAnimationFailure;
    private Color mainColor;
    private Color secondaryColor;
    private Color checkMarkTintColor;
    private Color failureMarkTintColor;
    private Color textColor;
    private final String MAIN_COLOR = "mainColor";
    private final String SECOND_COLOR = "secondaryColor";
    private final String CHECK_MARK_TINT_COLOR = "checkMarkTintColor";
    private final String FAILURE_MARK_TINT_COLOR = "failureMarkTintColor";
    private final String TEXT_COLOR = "textColor";
    private AttrUtil attrUtil;

    public AnimatedCircleLoadingView(Context context) {
        super(context);
        this.context = context;
    }

    public AnimatedCircleLoadingView(Context context, AttrSet attrs) {
        super(context, attrs);
        this.context = context;
        initAttributes(attrs);
    }

    public AnimatedCircleLoadingView(Context context, AttrSet attrs, String defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = context;
        initAttributes(attrs);
    }

    private void initAttributes(AttrSet attrs) {
        attrUtil = new AttrUtil(attrs);
        mainColor = attrUtil.getAttrColor(MAIN_COLOR, new Color(DEFAULT_HEX_MAIN_COLOR));
        secondaryColor = attrUtil.getAttrColor(SECOND_COLOR, new Color((DEFAULT_HEX_SECONDARY_COLOR)));
        checkMarkTintColor = attrUtil.getAttrColor(CHECK_MARK_TINT_COLOR, new Color(DEFAULT_HEX_TINT_COLOR));
        failureMarkTintColor = attrUtil.getAttrColor(FAILURE_MARK_TINT_COLOR, new Color(DEFAULT_HEX_TINT_COLOR));
        textColor = attrUtil.getAttrColor(TEXT_COLOR, new Color(DEFAULT_HEX_TEXT_COLOR));
    }

    private void startAnimation() {
        if (getWidth() != 0 && getHeight() != 0) {
            if (startAnimationIndeterminate) {
                viewAnimator.startAnimator();
                startAnimationIndeterminate = false;
            }
            if (startAnimationDeterminate) {
                addComponent(percentIndicatorView, getWidth(), getHeight());
                viewAnimator.startAnimator();
                startAnimationDeterminate = false;
            }
            if (stopAnimationOk) {
                stopOk();
            }
            if (stopAnimationFailure) {
                stopFailure();
            }
        }
    }

    private void init() {
        initComponents();
        addComponentsViews();
        initAnimatorHelper();
    }

    private void initComponents() {
        int width = getWidth();
        initialCenterCircleView =
                new InitialCenterCircleView(context, width, mainColor, secondaryColor);
        rightCircleView = new RightCircleView(context, width, mainColor, secondaryColor);
        sideArcsView = new SideArcsView(context, width, mainColor, secondaryColor);
        topCircleBorderView = new TopCircleBorderView(context, width, mainColor, secondaryColor);
        mainCircleView = new MainCircleView(context, width, mainColor, secondaryColor);
        finishedOkView =
                new FinishedOkView(context, width, mainColor, secondaryColor, checkMarkTintColor);
        finishedFailureView =
                new FinishedFailureView(context, width, mainColor, secondaryColor, failureMarkTintColor);
        percentIndicatorView = new PercentIndicatorView(context, width, textColor);
    }

    private void addComponentsViews() {
        addComponent(initialCenterCircleView);
        addComponent(rightCircleView);
        addComponent(sideArcsView);
        addComponent(topCircleBorderView);
        addComponent(mainCircleView);
        addComponent(finishedOkView);
        addComponent(finishedFailureView);
    }

    private void initAnimatorHelper() {
        viewAnimator = new ViewAnimator();
        viewAnimator.setAnimationListener(animationListener);
        viewAnimator.setComponentViewAnimations(initialCenterCircleView, rightCircleView, sideArcsView,
                topCircleBorderView, mainCircleView, finishedOkView, finishedFailureView,
                percentIndicatorView);
    }

    public void startIndeterminate() {
        startAnimationIndeterminate = true;
        init();
        startAnimation();
    }

    public void startDeterminate() {
        startAnimationDeterminate = true;
        init();
        startAnimation();
    }

    public void setPercent(int percent) {
        if (percentIndicatorView != null) {
            percentIndicatorView.setPercent(percent);
            if (percent == 100) {
                viewAnimator.finishOk();
            }
        }
    }

    public void stopOk() {
        if (viewAnimator == null) {
            stopAnimationOk = true;
        } else {
            viewAnimator.finishOk();
        }
    }

    public void stopFailure() {
        if (viewAnimator == null) {
            stopAnimationFailure = true;
        } else {
            viewAnimator.finishFailure();
        }
    }

    public void resetLoading() {
        if (viewAnimator != null) {
            viewAnimator.resetAnimator();
        }
        setPercent(0);
    }

    public void setAnimationListener(AnimationListener animationListener) {
        this.animationListener = animationListener;
    }

    public interface AnimationListener {
        void onAnimationEnd(boolean success);
    }
}
